#include <iostream>
#include <vector>
#include <fstream>
//#include "kmp.cpp"
#include <omp.h>
#include "sopa.hpp"
#include <locale.h> 

using namespace std;


//Variables Globales
sopaDeLetras *sopa;


void inicializar(vector<wchar_t *>&,char*,char*);
void imprimeVector(vector<wchar_t *>);
int	utf8_decode(char *B, unsigned int &len, unsigned int despl);
void imprime_wchar_t(wchar_t *);

int main(int argc, char **argv){
	
	//**********bloque de variables**********
	//vector de palabras
	vector<wchar_t *> palabras;
	wchar_t celda;
	char archivo_sopa[20], archivo_palabras[20];
	int encontrada=0;
	int procesos_disponibles;
	int id_hilos;
	//**********bloque de variables**********
	//Si no se define en el argumento los archivos de entrada
	if(argc < 3){
		strcpy(archivo_sopa,"sopa1");
		strcpy(archivo_palabras,"palabras1");
		cout<<"No se especifico archivos de entrada, por defecto funciona con sopa1, palabras1"<<endl;
	}
	else{
		strcpy(archivo_sopa,argv[1]);
		strcpy(archivo_palabras,argv[2]);
	}
	inicializar(palabras,archivo_sopa,archivo_palabras);


	//sopa->toUpper();
	cout<<"lista de palabras:"<<endl;
	imprimeVector(palabras);
	cout<<"sopa:"<<endl;
	sopa->imprime();
	//******* Fijo hilos segun disponibilidad *********//
	procesos_disponibles = omp_get_num_procs(); 
	omp_set_num_threads(procesos_disponibles);
	//******* Fijo hilos segun disponibilidad *********//

	printf("Hilos disponibles: %d\n", procesos_disponibles);
	//nucleo del programa
	#pragma omp parallel for //Paralelizo ciclo for
	for(int i=0;i<sopa->getW();i++){
		for(int j=0;j<sopa->getH();j++){
			celda = sopa->buscarRelativo(i,j,0,1);
			for (int k = 0;k < palabras.size();k++){
				if(palabras[k][0]==celda){
					//Hasta aqui se encontro que la celda coincide con la 1era letra de la palabra
					//For de direccion
					for(int d=1;(d<9) && (!encontrada);d++){
						//for en profundidad
						for(int r=1;r<wcslen(palabras[k]);r++){
							if(sopa->buscarRelativo(i,j,r,d) != palabras[k][r])break;
							if(r == (wcslen(palabras[k])-1)){
								cout<<"ENCONTRADO:";
								imprime_wchar_t(palabras[k]);
								cout<<". posicion:"<<i<<","<< j<<"direccion:"<<d<<endl;
								encontrada = 1;
								palabras.erase(palabras.begin()+k);
								cout<<"quedan:"<<palabras.size()<<endl;
							}
						}
					}
					encontrada=0;
				}
			}
		}

	}

}

	

void inicializar(vector<wchar_t *> &palabras, char *archivo_sopa, char *archivo_palabras){
	FILE *f;
	char B[LENMAX], byte[1];
	unsigned int despl = 0, len = 0;
	wchar_t caracter;
	wchar_t *p;
	char direccion_sopa[30]="ejemplos/", direccion_palabras[30]="ejemplos/";
	strcat(direccion_sopa,archivo_sopa);
	strcat(direccion_palabras,archivo_palabras);
	
	f = fopen(direccion_palabras,"rb");
	while(1){
		p = (wchar_t*)malloc(sizeof(wchar_t)*LENMAX);
		despl=0;
		len=0;
		byte[0]=0;
		//Inicializa B y p
		for(int i=0;i<LENMAX;i++){B[i]=0;p[i]=0;}

		/*Lee desde el archivo hasta un blanco o salto de linea o fin de archivo*/
		/*Asume que la linea es no vacia*/
		for(int i=0;i<LENMAX;i++){
			fread(byte,1,1,f);
			if((byte[0] != 10)){
				B[i] = byte[0];
			}
			else break;
		}
		if(strlen(B)==0)break;

		/*Pasa de B, que contiene bytes a p que contiene un arreglo de wide characters*/
		for(int i=0;B[despl] != 0;i++){
			caracter = utf8_decode(B, len, despl);
			despl += len;
			len = 0;
			p[i] = caracter;
		}
		//Agrega la palabra p (en UTF32) al vector
		palabras.push_back(p);
	}

	fclose(f);

	//Se abre el archivo que contiene la sopa
	f = fopen(direccion_sopa,"rb");
	sopa = new sopaDeLetras(f);

}

void imprimeVector(vector<wchar_t *> v){
	for (vector<wchar_t *>::iterator i = v.begin();i!=v.end();i++){
		imprime_wchar_t(*i);
		cout<<endl;
	}
}

void imprime_wchar_t(wchar_t *wp){
	for(int j=0;j<wcslen(wp);j++)cout<<wp[j]<<"-";

}



/*
- Pequeño analisis algoritmico en el informe
- Corregir lectura de la sopa.. LISTO
- Tratar de mejorar algoritmo.. LISTO
- Ver si es posible imprimir en terminal caracteres utf32
- Archivos de entrada por argumento.. LISTO


Pruebas:
- Secuencial y paralelo
- Ascii y unicode
- Tamaño de lissta de palabras (2000,6000,12000,18000)
*/
